/*********************************************************************
*                SEGGER Microcontroller GmbH & Co. KG                *
*        Solutions for real time microcontroller applications        *
**********************************************************************
*                                                                    *
*        (c) 1996 - 2012  SEGGER Microcontroller GmbH & Co. KG       *
*                                                                    *
*        Internet: www.segger.com    Support:  support@segger.com    *
*                                                                    *
**********************************************************************

** emWin V5.18 - Graphical user interface for embedded applications **
All  Intellectual Property rights  in the Software belongs to  SEGGER.
emWin is protected by  international copyright laws.  Knowledge of the
source code may not be used to write a similar product.  This file may
only be used in accordance with a license and should not be re-
distributed in any way. We appreciate your understanding and fairness.
----------------------------------------------------------------------
File        : LCDConf.c
Purpose     : Display controller configuration (single layer)
---------------------------END-OF-HEADER------------------------------
*/

#include "GUI.h"
#include <stddef.h>

#include "GUIDRV_Lin.h"
#include "lcd_cortex.h"
#include "lpc_types.h"
#include "LPC177x_8x.h"
#include "system_LPC177x_8x.h"
#include "HWConf.h"
#include "LCDConf.h"
#include "touch.h"


/*********************************************************************
*
*       Layer configuration (to be modified)
*
**********************************************************************
*/

//
// Display framebuffer size
// These values can be reduced if using a smaller display and might have
// to be adjusted if using virtual screens. The values will be checked
// during emWin init.
//
#define FB_XSIZE  320
#define FB_YSIZE  240

//
// Physical display size
//

#define XSIZE_PHYS  320
#define YSIZE_PHYS  240

//
// Virtual display size
//
#define VXSIZE_PHYS (XSIZE_PHYS)
#define VYSIZE_PHYS (YSIZE_PHYS)

//
// Color conversion
//
#define COLOR_CONVERSION  GUICC_555

//
// Pixel width in bytes
//
#define PIXEL_WIDTH  2

//
// Display driver
//
#define DISPLAY_DRIVER_TRULY  &GUIDRV_Lin_16_API

//
// Video RAM address
//
#define VRAM_ADDR_PHYS  (U32)&_aVRAM[0]


/*********************************************************************
*
*       Configuration checking
*
**********************************************************************
*/
#ifndef   VXSIZE_PHYS
  #define VXSIZE_PHYS XSIZE_PHYS
#endif
#ifndef   VYSIZE_PHYS
  #define VYSIZE_PHYS YSIZE_PHYS
#endif
#ifndef   VRAM_ADDR_PHYS
  #define VRAM_ADDR_PHYS  0
#endif
#ifndef   VRAM_ADDR_VIRT
  #define VRAM_ADDR_VIRT  0
#endif

#ifndef   XSIZE_PHYS
  #error Physical X size of display is not defined!
#endif
#ifndef   YSIZE_PHYS
  #error Physical Y size of display is not defined!
#endif
#ifndef   COLOR_CONVERSION
  #error Color conversion not defined!
#endif

/*********************************************************************
*
*       Defines
*
**********************************************************************
*/

//320/240 -Glyn
const LCD_PARAM_T get0350g0dh6 =
{
		68,      // Horizontal back porch 88
		20,      // Horizontal front porch 40
		28,     // HSYNC pulse width 128
		320,     // Pixels per line bylo 800
		18,       // Vertical back porch 33
		4,       // Vertical front porch 10
		2,      // VSYNC pulse width
		240,     // Lines per panel
		0,       // Invert output enable
		1,       // Do not invert panel clock
		1,       // Invert HSYNC
		1,       // Invert VSYNC
		1,       // AC bias frequency (not used)
		16,      // Bits per pixel
		4800000, // Optimal clock rate (Hz)
		TFT,     // LCD panel type
		0,       // Single panel display
};

//
// LCD types
//
enum {
  DISPLAY_TRULY_240_320,
  DISPLAY_BOARD_480_272,
  DISPLAY_BOARD_800_480
};


//
// LCDC
//
#define LCDC_BPP_16_565    6     // Bits per pixel b110 = 16 bpp 5:6:5 mode
#define LCDC_TFT           1     // TFT value for LCDC

#define BGR                0     // Swap red and blue

#define BCD_BIT            26    // Bypass pixel clock divider
#define LCD_BACKLIGHT_BIT  18    // P1.18
#define LCD_REG_BIT        19    // P0.19

#define LCD_DATA()         (LPC_GPIO0->SET = (1 << LCD_REG_BIT))
#define LCD_CMD()          (LPC_GPIO0->CLR = (1 << LCD_REG_BIT))

#define LCDRST_OFF 	LPC_GPIO0->PIN |= (1<<17)
#define LCDRST_ON 	LPC_GPIO0->PIN &= ~(1<<17)

#define LCD_POWER_OFF  LPC_GPIO2->PIN |= (1<<0)
#define LCD_POWER_ON  LPC_GPIO2->PIN &= ~(1<<0)

#define BUZZER_ON 	LPC_GPIO0->PIN |= (1<<6)
#define BUZZER_OFF LPC_GPIO0->PIN &= ~(1<<6)

#ifndef   ABS
  #define ABS(x)                       (((int32_t)(x)) < 0 ? (-x) : (x))
#endif

/*********************************************************************
*
*       Defines, sfrs
*
**********************************************************************
*/

#define MATRIX_ARB  (*(volatile U32*)(0x400FC188))

/*********************************************************************
*
*       Types
*
**********************************************************************
*/



/*********************************************************************
*
*       Static data
*
**********************************************************************/

//
// Video RAM
//
#ifdef __GNUC__
  U32 static _aVRAM[FB_XSIZE * FB_YSIZE]  __attribute__ ((section(".VRAM"))) = { 0 };
#endif

/*********************************************************************
*
*       Local functions
*
**********************************************************************
*/


/*********************************************************************
*
*       _SetDisplayOrigin()
*/
#ifndef _WINDOWS
static void _SetDisplayOrigin(int x, int y) {
  (void)x;
  //
  // Set start address for display data and enable LCD controller
  //
  //LPC_LCD->UPBASE = VRAM_ADDR_PHYS + (y * YSIZE_PHYS * PIXEL_WIDTH);  // Needs to be set, before LCDC is enabled
}
#endif




/*********************************************************************
*
*       Local functions for display selection and LCDC init
*
**********************************************************************
*/


/*
*       LCD_X_Config
*
* Purpose:
*   Called during the initialization process in order to set up the
*   display driver configuration.
*/
long dev_lcd;

void _InitController(unsigned LayerIndex)
{
	int i;
	unsigned int count;
	unsigned short *tftptr;

	//czyszczenie pierwszego scrren przed funkcja Welcome
	tftptr = (unsigned short *)VRAM_ADDR_PHYS;
	count = 2*320*240;
	for(i=0;i<count;i++)
	{
	    *tftptr++=0x1234;
	}

    LPC_SC->PCONP |= 0x1;

	if ((dev_lcd = lcd_open(/*CLCDC, */(long)&get0350g0dh6)) == 0x0)
	{
		//Error opening the device
		while(1);
	}

	// Set LCD display pointer
	lcd_ioctl(dev_lcd, LCD_SET_BUFFER, (long)VRAM_ADDR_PHYS);

	// Set RGB -> BGR
	lcd_ioctl(dev_lcd, LCD_SET_BGR, 0);

	lcd_ioctl(dev_lcd, LCD_DMA_ON_4MT, 0);

	//=======Interrupt===================
			//init_lcd_int();

	//===================================


	// Enable LCD
	lcd_ioctl(dev_lcd, LCD_ENABLE, 1);
	// Turn on LCD
	lcd_ioctl(dev_lcd, LCD_PWR_ON, 1);
	LCD_POWER_SET;

	vTouch_Init();
}

void LCD_X_Config(void)
{

  GUI_DEVICE_CreateAndLink(DISPLAY_DRIVER_TRULY, COLOR_CONVERSION, 0, 0);
  LCD_SetPosEx(0, 0, 0);

  if (LCD_GetSwapXY()) {
    LCD_SetSizeEx (0, YSIZE_PHYS, XSIZE_PHYS);
    LCD_SetVSizeEx(0, YSIZE_PHYS, XSIZE_PHYS);
  } else {
    LCD_SetSizeEx (0, XSIZE_PHYS, YSIZE_PHYS);
    LCD_SetVSizeEx(0, XSIZE_PHYS, YSIZE_PHYS);
  }
  LCD_SetVRAMAddrEx(0, (void*)VRAM_ADDR_PHYS);

}

/*********************************************************************
*
*       LCD_X_DisplayDriver
*
* Purpose:
*   This function is called by the display driver for several purposes.
*   To support the according task the routine needs to be adapted to
*   the display controller. Please note that the commands marked with
*   'optional' are not cogently required and should only be adapted if
*   the display controller supports these features.
*
* Parameter:
*   LayerIndex - Index of layer to be configured
*   Cmd        - Please refer to the details in the switch statement below
*   pData      - Pointer to a LCD_X_DATA structure
*
* Return Value:
*   < -1 - Error
*     -1 - Command not handled
*      0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
  #ifndef _WINDOWS
  LCD_X_SETORG_INFO * pSetOrg;
  #endif
  int r;

  (void) LayerIndex;

  switch (Cmd) {
  //
  // Required
  //
  case LCD_X_INITCONTROLLER:
    //
    // Called during the initialization process in order to set up the
    // display controller and put it into operation. If the display
    // controller is not initialized by any external routine this needs
    // to be adapted by the customer...
    //
    // ...
    #ifndef _WINDOWS
      _InitController(0);
    #endif
    return 0;
  case LCD_X_SETORG:
    //
    // Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p
    //
    #ifndef _WINDOWS
      pSetOrg = (LCD_X_SETORG_INFO *)pData;
      _SetDisplayOrigin(pSetOrg->xPos, pSetOrg->yPos);
    #endif
    return 0;
  default:
    r = -1;
  }
  return r;
}

void ExecTouch()
{

}

/*************************** End of file ****************************/
